package com.keray.common.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.keray.common.entity.IBEntity;
import com.keray.common.entity.IBSEntity;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;

/**
 * @author by keray
 * date:2019/12/4 2:14 PM
 */
@Slf4j
public final class CommonUtil {
    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/12/4 2:15 PM</h3>
     * 寻找某个class是否有某个注解 包括向上的接口，父类
     * </p>
     *
     * @param clazz
     * @param annotation
     * @return <p> {@link boolean} </p>
     * @throws
     */
    public static boolean classAllSuperHaveAnnotation(Class<?> clazz, Class<? extends Annotation> annotation) {
        if (clazz.getAnnotation(annotation) != null) {
            return true;
        }
        if (clazz.getSuperclass() == null) {
            return false;
        }
        return classAllSuperHaveAnnotation(clazz.getSuperclass(), annotation);
    }

    public static <A extends Annotation> A getClassAllAnnotation(Class<?> clazz, Class<A> annotation) {
        if (clazz.getAnnotation(annotation) != null) {
            return clazz.getAnnotation(annotation);
        }
        if (clazz.getSuperclass() == null) {
            return null;
        }
        return getClassAllAnnotation(clazz.getSuperclass(), annotation);
    }

    public static Class<?> superHaveClass(Class<?> owner, Class<?> target) {
        if (owner.equals(Object.class)) {
            return null;
        }
        if (owner.getSuperclass().equals(target)) return owner;
        return superHaveClass(owner.getSuperclass(), target);
    }

    public static BigDecimal moneyTrans(double num) {
        return BigDecimal.valueOf((long) (num * 100), 2);
    }

    public static String mybatisPluginsModel2Sql(IBEntity<?> model) {
        StringJoiner stringJoiner = new StringJoiner("and");
        List<Field> fields = model.scanFields(model.getClass(), null);
        int index = 0;
        for (Field field : fields) {
            TableField tableField = field.getAnnotation(TableField.class);
            if (tableField != null && !tableField.exist()) {
                continue;
            }
            try {
                Method get = model.scanMethod(model.getClass(), "get" + StrUtil.upperFirst(field.getName()));
                if (get == null) {
                    continue;
                }
                Object result = get.invoke(model);
                if (ObjectUtil.isNotEmpty(result)) {
                    if (tableField == null) {
                        stringJoiner.add(String.format(" `%s` = {%s}", field.getName(), index++));
                    }
                }
            } catch (Exception e) {
                log.error("not here", e);
            }
        }
        return stringJoiner.toString();
    }

    public static Object[] mybatisPluginsModel2SqlValue(IBEntity<?> model) {
        List<Object> values = new LinkedList<>();
        List<Field> fields = model.scanFields(model.getClass(), null);
        for (Field field : fields) {
            TableField tableField = field.getAnnotation(TableField.class);
            if (tableField != null && !tableField.exist()) {
                continue;
            }
            try {
                Method get = model.scanMethod(model.getClass(), "get" + StrUtil.upperFirst(field.getName()));
                if (get == null) {
                    continue;
                }
                Object result = get.invoke(model);
                if (ObjectUtil.isNotEmpty(result)) {
                    values.add(result);
                }
            } catch (Exception e) {
                log.error("not here", e);
            }
        }
        return values.toArray(new Object[0]);
    }

    public static String hostIp() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            String firstIp = null;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    ip = addresses.nextElement();
                    String retIp = ip.getHostAddress();
                    if (firstIp == null) {
                        firstIp = retIp;
                    }
                    if (retIp.matches("192\\.168.*")) {
                        return retIp;
                    }
                }

            }
            return firstIp;
        } catch (Exception e) {
            return "";
        }
    }

    public static String mobileSafe(String mobile) {
        if (StrUtil.isBlank(mobile) || mobile.length() != 11) return mobile;
        return mobile.substring(0, 3) + "****" + mobile.substring(7, 11);
    }
}
